package pers.zb.cloud.service.upms.service.impl;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import pers.zb.cloud.service.upms.dao.*;
import pers.zb.cloud.service.upms.entity.*;
import pers.zb.cloud.service.upms.enums.MenuStatus;
import pers.zb.cloud.service.upms.service.ClientDetailService;
import pers.zb.cloud.service.upms.service.RoleService;
import pers.zb.cloud.service.upms.util.RoleClientPermissionTreeUtil;
import pers.zb.cloud.service.upms.util.sequence.IdWorker;
import pers.zb.cloud.service.upms.vo.*;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

@Service("roleServiceImpl")
public class RoleServiceImpl extends BaseServiceImpl<SysRole> implements RoleService {

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private RoleOperateLogMapper roleOperateLogMapper;

    @Autowired
    private ClientDetailService clientDetailService;

    @Autowired
    private RoleClientAuthorizeMapper roleClientAuthorizeMapper;

    @Autowired
    private PermissionMapper permissionMapper;

    @Autowired
    private RoleClientPermissionMapper roleClientPermissionMapper;

    @Override
    public SysRole getRoleById(Long roleId) {
        return roleMapper.selectByPrimaryKey(roleId);
    }

    @Override
    public Page<SysRole> getRoleListForPage(Page pageParam, SysRole roleParam) {
        //所有记录数
        List<SysRole> roleAll = roleMapper.selectAll();
        int totalRow = roleAll.size();

        if(pageParam == null || roleParam == null){
            return new Page<>();
        }
        //条件分页查询列表
        List<SysRole> roleList = roleMapper.getRoleList(pageParam, roleParam);
        return new Page(roleList, pageParam, totalRow);
    }

    @Override
    public void updateOrSave(int type, SysRole sysRole) throws Exception {
        if(sysRole == null){
            throw new Exception("角色对象为null");
        }
        if(StringUtils.isEmpty(sysRole.getName())){
            throw new Exception("角色名称不能为空");
        }

        if(type == 1){//更新
            sysRole.setUpdateTime(new Date());
            roleMapper.updateByPrimaryKeySelective(sysRole);
        }else { //添加
            Example example = new Example(SysRole.class);
            example.createCriteria().andEqualTo("name",sysRole.getName());
            List<SysRole> sysRoleObject = roleMapper.selectByExample(example);
            if(sysRoleObject != null && sysRoleObject.size() > 0){//名称重复
                throw new Exception("角色名称已经存在");
            }
            sysRole.setId(IdWorker.id.nextId());
            sysRole.setCreateTime(new Date());
            sysRole.setUpdateTime(new Date());
            roleMapper.insert(sysRole);
        }
    }

    @Override
    public void deleteRole(Long[] roleIdArrs) throws Exception {
        if(roleIdArrs == null){
            throw new Exception("请选择需要删除的角色");
        }

        Example example = new Example(SysRole.class);
        example.createCriteria().andIn("id", Arrays.asList(roleIdArrs));
        roleMapper.deleteByExample(example);
    }

    @Override
    public Page<SysRoleOperateLog> getRoleOperateLogForPage(Page pageParam, SysRoleOperateLog roleOperateLogParam) {
        if(roleOperateLogParam.getRoleId() == null){
            return new Page(new ArrayList<>(), pageParam, 0);
        }
        //所有记录数
        List<SysRoleOperateLog> roleOperateLogAll = roleOperateLogMapper.selectAll();
        int totalRow = roleOperateLogAll.size();

        if(pageParam == null || roleOperateLogParam == null){
            return new Page<>();
        }
        //条件分页查询列表
        List<SysRoleOperateLog> roleOperateLogList = roleOperateLogMapper.getRoleOperateLogListForPage(pageParam, roleOperateLogParam);
        return new Page(roleOperateLogList, pageParam, totalRow);
    }

    @Override
    public List<RolePermissionVo> getRolePermissionTreeList(Long roleId) {
        //获取角色拥有的权限
        return null;
    }

    @Override
    public List<RoleClientAuthorizeVo> getRoleClientAuthorizeList(Long roleId) {
        //获取所有应用
        List<ClientDetail> clientDetailAllList = clientDetailService.selectAllClientDetailList();

        //获取角色已经授权的应用
        Example example = new Example(SysRoleClientAuthorize.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("roleId",roleId);
        List<SysRoleClientAuthorize> sysRoleClientAuthorizes = roleClientAuthorizeMapper.selectByExample(example);

        return SettingRoleClientAuthorize(clientDetailAllList,sysRoleClientAuthorizes);
    }

    /**
     * 为角色设置应用的访问权限
     *
     * @param roleId 角色ID
     * @param clientIdArrString 应用的client_id集合，逗号分隔
     */
    @Transactional
    @Override
    public void roleClientAuthorize(Long roleId, String[] clientIdArrString) {
        //先删除角色拥有的应用的访问权限
        Example example = new Example(SysRoleClientAuthorize.class);
        example.createCriteria().andEqualTo("roleId",roleId);
        roleClientAuthorizeMapper.deleteByExample(example);

        //为角色添加应用的可访问权限
        if(clientIdArrString == null || clientIdArrString.length <= 0){
            return;
        }
        for (String clientId : clientIdArrString) {
            SysRoleClientAuthorize sysRoleClientAuthorize = new SysRoleClientAuthorize();
            sysRoleClientAuthorize.setClientId(clientId);
            sysRoleClientAuthorize.setRoleId(roleId);
            sysRoleClientAuthorize.setId(IdWorker.id.nextId());
            roleClientAuthorizeMapper.insert(sysRoleClientAuthorize);
        }
    }

    /**
     * 获取角色拥有应用访问权限的应用列表
     *      from : 角色管理 -> 角色权限设置 -> 角色已授权系统
     *
     * @param roleId 角色ID
     */
    @Override
    public List<ClientVo> getRoleClientAuthorizeListTree(Long roleId) {
        Example example = new Example(SysRoleClientAuthorize.class);
        example.createCriteria().andEqualTo("roleId",roleId);
        List<SysRoleClientAuthorize> sysRoleClientAuthorizes = roleClientAuthorizeMapper.selectByExample(example);

        List<ClientVo> roleClientAuthorizeList = new ArrayList<>();
        if(sysRoleClientAuthorizes == null || sysRoleClientAuthorizes.size() <= 0){
            return roleClientAuthorizeList;
        }

        List<ClientVo> roleClientAuthorizeChildrenVos = new ArrayList<ClientVo>();
        //模拟一个父节点
        ClientVo clientVoParent = new ClientVo();
        clientVoParent.setName("电商业务系统");
        clientVoParent.setState("closed");
        clientVoParent.setId("-1");

        for (SysRoleClientAuthorize sysRoleClientAuthorize: sysRoleClientAuthorizes) {
            ClientVo clientVo = new ClientVo();
            clientVo.setName(sysRoleClientAuthorize.getClientId());
            clientVo.setId(sysRoleClientAuthorize.getClientId());
            clientVo.setState("open");
            clientVo.setPid(clientVoParent.getId());
            clientVo.setRoleId(roleId);
            roleClientAuthorizeChildrenVos.add(clientVo);
        }
        clientVoParent.setChildren(roleClientAuthorizeChildrenVos);
        roleClientAuthorizeList.add(clientVoParent);

        return roleClientAuthorizeList;
    }

    /**
     * 获取角色在应用中的权限
     *
     * @param roleId 角色ID
     * @param clientId 应用的client_id
     * @param permissionId 权限ID
     */
    @Override
    public List<RoleClientPermissionVo> getRoleClientPermissionList(Long roleId, String clientId, Long permissionId) {
        Example example = new Example(SysPermission.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("pid",permissionId).andNotEqualTo("status", MenuStatus.DELETE);

        if(!StringUtils.isBlank(clientId) && !clientId.equals("-1")){ // -1 表示的是最顶层的父节点，也就是我们自定义的分组名称，该节点不是一个应用 。 具体业务代码请看 getClientListTree 方法。
            criteria.andEqualTo("clientId",clientId);
        }
        List<SysPermission> sysPermissionList = permissionMapper.selectByExample(example);

        List<RoleClientPermissionVo> roleClientPermissionVoList = new ArrayList<>();
        if(sysPermissionList == null || sysPermissionList.size() <= 0){
            return roleClientPermissionVoList;
        }

        Example roleClientPermissionExample = new Example(SysRoleClientPermission.class);
        Example.Criteria roleClientPermissionCriteria = roleClientPermissionExample.createCriteria();
        roleClientPermissionCriteria.andEqualTo("roleId",roleId).andEqualTo("clientId",clientId);
        //获取角色在应用中的权限
        List<SysRoleClientPermission> sysRoleClientPermissionList = roleClientPermissionMapper.selectByExample(roleClientPermissionExample);

        for (SysPermission sysPermission : sysPermissionList) {
            RoleClientPermissionVo roleClientPermissionVo = new RoleClientPermissionVo();
            roleClientPermissionVo.setId(sysPermission.getId());
            roleClientPermissionVo.setPid(sysPermission.getPid());
            roleClientPermissionVo.setCode(sysPermission.getCode());
            roleClientPermissionVo.setName(sysPermission.getName());
            roleClientPermissionVo.setType(sysPermission.getType());
            roleClientPermissionVo.setState(sysPermission.getShape().getValue());
            roleClientPermissionVo.setIconCls(sysPermission.getIcon());
            roleClientPermissionVo.setOauthStatus("no");//默认未授权该权限

            //判断是否拥有此权限的分配
            for (SysRoleClientPermission sysRoleClientPermission : sysRoleClientPermissionList) {
                //说明具有该权限的访问权限
                if(sysRoleClientPermission.getPermissionId().longValue() == sysPermission.getId().longValue()){
                    roleClientPermissionVo.setChecked(true);
                    roleClientPermissionVo.setOauthStatus("yes");
                    break;
                }
            }

            roleClientPermissionVoList.add(roleClientPermissionVo);
        }

        //对于拥有子菜单的菜单，递归获取所有层级的子菜单数据
        List<RoleClientPermissionVo> permissionTreeList =  RoleClientPermissionTreeUtil.getPermissionTreeList(roleClientPermissionVoList,permissionId);
        return permissionTreeList;
    }

    /**
     * 为角色设置应用的功能操作权限
     *
     * @param clientId 应用client_id
     * @param roleId 角色ID
     * @param permissionIdArrString 权限ID
     */
    @Transactional
    @Override
    public void settingRoleClientPermission(String clientId, Long roleId, Long[] permissionIdArrString) {
        //先删除角色对应的应用的功能操作权限
        Example example = new Example(SysRoleClientPermission.class);
        example.createCriteria().andEqualTo("roleId",roleId).andEqualTo("clientId",clientId);
        roleClientPermissionMapper.deleteByExample(example);

        //为角色添加应用的功能操作权限
        if(permissionIdArrString == null || permissionIdArrString.length <= 0){
            return;
        }
        for (Long permissionId : permissionIdArrString) {
            SysRoleClientPermission sysRoleClientPermission = new SysRoleClientPermission();
            sysRoleClientPermission.setClientId(clientId);
            sysRoleClientPermission.setRoleId(roleId);
            sysRoleClientPermission.setId(IdWorker.id.nextId());
            sysRoleClientPermission.setPermissionId(permissionId);
            roleClientPermissionMapper.insert(sysRoleClientPermission);
        }
    }

    /**
     * 设置角色授权的应用
     *
     * @param clientDetailAllList 所有应用列表
     * @param sysRoleClientAuthorizes 角色已经授权的应用
     * @return
     */
    private List<RoleClientAuthorizeVo> SettingRoleClientAuthorize(List<ClientDetail> clientDetailAllList , List<SysRoleClientAuthorize> sysRoleClientAuthorizes){
        List<RoleClientAuthorizeVo> permissionVoList = new ArrayList<>();

        //即使角色未授权任何应用，前端tree还是需要展示所有应用列表，只是checked为不选中状态
        for (ClientDetail clientDetail : clientDetailAllList) {
            RoleClientAuthorizeVo roleClientAuthorizeVo = new RoleClientAuthorizeVo();
            roleClientAuthorizeVo.setId(clientDetail.getClientId());
            roleClientAuthorizeVo.setName(clientDetail.getClientId());
            roleClientAuthorizeVo.setAuthorize("noAuthorize");

            //角色未授权任何应用
            if(sysRoleClientAuthorizes != null && sysRoleClientAuthorizes.size() > 0){
                for (SysRoleClientAuthorize sysRoleClientAuthorize : sysRoleClientAuthorizes) {
                    //角色授权了该应用
                    if(sysRoleClientAuthorize.getClientId().equals(clientDetail.getClientId())){
                        roleClientAuthorizeVo.setChecked(true);
                        roleClientAuthorizeVo.setAuthorize("yesAuthorize");
                        break;
                    }
                }
            }
            permissionVoList.add(roleClientAuthorizeVo);
        }
        return permissionVoList;
    }
}
